package first.endtoend;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.gemalto.minidriver.IMinidriver;

/**
 * This Class is created to connect M-PDS with IDGo800 PKI service 
 * Before being able to use methods of the AIDL Files, M-PDS must connect to IDGo800 PKI service.
 * to do so M-PDS must send a bind request to the service 
 * and implement a ServiceConnection callback that will receive the service instance.   
 * */

public class IDGoBindingActivity extends MyActivity {
	
	private static final String TAG = "IDGoService";
	
	//we can use more than one interface in the service 
	IMinidriver m_pkiService=null; //instance of the IMinidriver interface
	
	Minidriver minideriver_instance; //instance of the Minidriver Service
	private static int m_pkiSessionId=0; 
	private static final String testAppPackage= "first.endtoend";
	static String app_signature="0D64B7A6C26A4CBE8BEEA5DDA0265214";
	private static final byte[] testAppSignature = app_signature.getBytes(); 
	
	private Boolean mIsBound;
	Button mKillButton;
	TextView mCallbackText; 

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
//		setContentView(R.layout.activity_idgobinding);
//		getIntent();
//		Toast.makeText(getApplicationContext(), "Welcome to IDGo Activity!", Toast.LENGTH_SHORT).show();
//		
//	
//		Button btn = (Button) findViewById(R.id.btn_bind);
//		btn.setOnClickListener(mBindListener);
//		btn= (Button) findViewById(R.id.btn_unbind);
//		btn.setOnClickListener(mUnBindListener);
//		mKillButton  = (Button) findViewById(R.id.btn_kill);
//		mKillButton.setOnClickListener(mKillListener);
//		mKillButton.setEnabled(false);
//		
//		mCallbackText = (TextView) findViewById(R.id.txt_callback);
//		mCallbackText.setText("Not attached");
	}
	
	protected void onStart() {
		super.onStart();
		connectToPkiService(this);
	};
	
	//The serviceConnection that implements the Connection/Disconnection to the service callbacks. 
	private ServiceConnection m_pkiConnection = new ServiceConnection() {
		
	//for each interface we should instantiate a new ServiceConnection and call the interface.Stub.asInterface()
		
		
		//Called when the connection with the service disconnects unexpectedly
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			m_pkiService=null;
			mKillButton.setEnabled(false);
			mCallbackText.setText("Service Disconnected");
			
			try {
				//m_pkiService.MD_Finalize(m_pkiSessionId);
			} catch (Exception e) {
				// TODO: handle exception
			}
			//Tell the user what happens 
			Toast.makeText(IDGoBindingActivity.this, "Service has unexpectedly disconnected !!!", Toast.LENGTH_SHORT).show();
		}
		
		//Called when the connection with the service is established 
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			Log.i(TAG, "Connection with Service is established !");				
			Toast.makeText(IDGoBindingActivity.this, "Remote service connected", Toast.LENGTH_SHORT).show();
			 
			//to Get service instance
			m_pkiService = IMinidriver.Stub.asInterface(service);
			mKillButton.setEnabled(true);
			mCallbackText.setText("Attached to service");
			
			//to monitor the service as long as we are connected to it.
			try {
				//m_pkiService.registerCallback(mCallback);
				m_pkiSessionId= m_pkiService.MD_Init(-1, testAppPackage, testAppSignature);
				System.out.println("the session id is:"+m_pkiSessionId);
				
				Boolean transactionStatus = m_pkiService.MD_BeginTransaction(m_pkiSessionId);
					if(transactionStatus == true){
						//Toast.makeText(getApplicationContext(), "transaction can be established", Toast.LENGTH_LONG).show();
						System.out.println("transaction can be established");
					}
					else{
						//Toast.makeText(getApplicationContext(), "transaction can not be established ", Toast.LENGTH_LONG).show();
						System.out.println("transaction can not be established ");
					}
				
				int cardType = m_pkiService.MD_GetCardType(m_pkiSessionId);
				//Toast.makeText(getApplicationContext(), "the Card type is= "+cartType, Toast.LENGTH_LONG).show();
				System.out.println("the Card type is: "+cardType);
				
				String cardVersion = m_pkiService.MD_GetVersion(m_pkiSessionId);
				//Toast.makeText(getApplicationContext(), "the Card Version is= "+cardVersion, Toast.LENGTH_LONG).show();
				System.out.println("the Card Version is= "+cardVersion);
				
				int errors = m_pkiService.MD_GetLastError();
				//Toast.makeText(getApplicationContext(), "last errors are= "+errors, Toast.LENGTH_LONG).show();
				System.out.println("last errors are= "+errors);
				
//				byte ctrIndex= 0x00;
//				byte keySpec= 0x01;
//				m_pkiService.MD_CreateContainer(m_pkiSessionId, ctrIndex, false, keySpec, 4096, null);
//				byte[] container = m_pkiService.MD_GetContainer(m_pkiSessionId, ctrIndex);
//				//Toast.makeText(getApplicationContext(), "the container created is= "+container, Toast.LENGTH_LONG).show();
//				System.out.println("the container created is= "+container);
				
			} catch (Exception e) {
				// TODO: handle exception
			}
			
		}
	};
	

	private OnClickListener mBindListener = new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			Intent intent = new Intent(IDGoBindingActivity.this, Minidriver.class); 
			intent.setAction(IMinidriver.class.getName());
			bindService(intent, m_pkiConnection, Context.BIND_AUTO_CREATE);
			mIsBound= true;
			mCallbackText.setText("Binding Service");
		}
	};
	
	private OnClickListener mUnBindListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			if(mIsBound){
				//if we have received the service, and hence registered with it
				//so now is the time to unregister.
				if(m_pkiService != null){
					try {
						m_pkiService.MD_Finalize(m_pkiSessionId);
						Toast.makeText(IDGoBindingActivity.this, "Service has crashed", Toast.LENGTH_SHORT).show();
					} catch (Exception e) {
						// TODO: handle exception
					}
				}
				//Detach the existing connection 
				unbindService(m_pkiConnection);
				mKillButton.setEnabled(false);
				mIsBound=false;
				mCallbackText.setText("Unbinding service");
			}
		}
	};
	
	private OnClickListener mKillListener = new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			//to kill the process hosting the service we need to know its PID.
			if (m_pkiConnection != null){
				try {
//					int pid= m_pkiConnection.getPid();
//					Process.killProcess(pid);
					m_pkiService.MD_EndTransaction(m_pkiSessionId);
					System.out.println("End transaction!!!");
					mCallbackText.setText("Killed service process");
				} catch (Exception e) {
					// TODO: handle exception
					Toast.makeText(IDGoBindingActivity.this, "Remote Call Failed !!!", Toast.LENGTH_SHORT).show();

				}
			}
		}
	};
	
	// send connection request
		private void connectToPkiService(Context context) {
			if (m_pkiService == null) {
				Intent intent = new Intent();
				intent.setComponent(new ComponentName("com.gemalto.minidriver","com.gemalto.minidriver.CardModuleService"));
				intent.setAction(IMinidriver.class.getName());
				context.bindService(intent, m_pkiConnection,Context.BIND_AUTO_CREATE);
				// bind the client to the remote service
				// Context.BIND_AUTO_CREATE ensures that a service is created
			}
		}
	
	
	
	//handler of a test button in activity UI 
	public void clickTestButton(View view){
		//Execute PKI sample in an AsyncTask to avoid to block activity UI
		new pkiSample().execute();
	}
	
	//AsyncTask to execute PKI Service Sample code 
	private class pkiSample extends AsyncTask<Void, Void, Integer>
	{

		@Override
		protected Integer doInBackground(Void... params) {
			// TODO Auto-generated method stub
			try {
				//Create Container to generate key-pair 
				//PKI service will automatically prompt for PIN entry if not already auth. 
				m_pkiService.MD_CreateContainer(m_pkiSessionId, (byte) 0xff, false, (byte) 0x01, 1024, null);
			} catch (Exception e) {
				// TODO: handle exception
				//OBKG Failed!
			}
			//return status of last method execution
			int err=0;
			try {
				err = m_pkiService.MD_GetLastError();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return err;
			
		}
		
		@Override
		protected void onPostExecute(Integer result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			if(result != 0){
				int error_nb;
				try {
					error_nb = m_pkiService.MD_GetLastError();
					Toast.makeText(getApplicationContext(), "Error nb:"+error_nb, Toast.LENGTH_LONG).show();
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("PKI Service method returned an error");
			}else{
				//RSA key Successfully Generated 
				System.out.println("RSA Successfully generated");
				Toast.makeText(getApplicationContext(), "RSA generation Success", Toast.LENGTH_LONG).show();
			}
		}
		
	}
	
//		
//		public void valueChanged (int value){
//			mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
//		}
//	};
//	
//	private static final int BUMP_MSG=1;
//	
//	private Handler mHandler = new Handler(){
//		public void handleMessage(android.os.Message msg) {
//			switch (msg.what) {
//			case BUMP_MSG:
//				mCallbackText.setText("Received from service:"+ msg.arg1);
//				break;
//
//			default:
//				super.handleMessage(msg);
//			}
//		};
//	};
}